﻿using MvCamCtrl.NET;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;

namespace 万向焊接单机
{
   
 
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Windows.Forms;
    using ExceptionCallBack = MyCamera.cbExceptiondelegate;
    using ImageCallBack = MyCamera.cbOutputdelegate;

    internal enum TriggerSelector
    {
        FrameBurstStart = 6,
        LineStart = 9,
    }

    public class HIKCamera
    {
        public const int CO_OK = 0;
        public const int CO_FAIL = -1;

        // 输出相机异常信息
        public event Action<string, string> OnError;

        // 手动触发、绘制模板时响应
        public event Action<string> OnManualImage;

        // 图像输出时响应
        public event Action<Bitmap> OnAutoImage;

        // 图像输出回调
        private ImageCallBack ImageCallback1;

        // 相机异常回调
        private ExceptionCallBack ExcCallback1;

        // 相机图像存储队列
        //public LockerQueue<HObject> ImageQueue = new LockerQueue<HObject>();
        public Queue<Bitmap> ImageQueue = new Queue<Bitmap>();


        /// <summary>
        ///单次采集 
        /// </summary>
        private bool ManualTrigger = false;

        /// <summary>
        /// 连续采集
        /// </summary>
        private bool IsContinuous = false;

        /// <summary>
        ///海康相机实例对象 
        /// </summary>
        private MyCamera m_Mycamera = null;

        /// <summary>
        ///实显示的时候是否显示十字中心 
        /// </summary>
        public bool HasCross = false;

        /// <summary>
        ///相机名称 
        /// </summary>
        private string _name = "";

        public string Name
        {
            get
            {
                return _name;
            }
        }

        private bool m_bOpen = false;


        /// <summary>
        ///相机打开状态 
        /// </summary>
        public bool IsOpen
        {
            get
            {
                return m_bOpen;
            }
        }

        private bool _isPreview;

        /// <summary>
        ///相机预览状态 
        /// </summary>
        public bool IsPreview
        {
            get
            {
                return _isPreview;
            }
        }

        /// <summary>
        /// 输出halcon图片
        /// </summary>
        public Bitmap OutputImage
        {
            get
            {
                if (ImageQueue.Count == 0)
                {
                    return null;
                }
                Bitmap obj = ImageQueue.Dequeue();
                //Console.WriteLine($"剩余图片数量：{ImageQueue.Length()}");
                return obj;
            }
        }

        /// <summary>
        /// 图像队列允许最大保存图像数量
        /// </summary>
        public int MaxImageCount { get; set; } = 5;

        public HIKCamera()
        {
            m_Mycamera = new MyCamera();
        }

        // ~HIKCamera()
        //{
        //    Close();

        //}
        //public void restartCam()
        //{
        //    //Uninit();
        //    Logger.Log(LogType.Begin,"重新连接相机");
        //    List<IntPtr> ls = new List<IntPtr>();
        //    EnumDevices(ref ls);
        //    //获取选择的设备信息
        //    Init(ls[0]);
        //}
        //public void Init(IntPtr ptrCam)
        //{
        //    int nRet = -1;
        //    //获取选择的设备信息
        //    MyCamera.MV_CC_DEVICE_INFO device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(ptrCam, typeof(MyCamera.MV_CC_DEVICE_INFO));
        //    if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
        //    {
        //        IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0);

        //        MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));

        //        _name = gigeInfo.chUserDefinedName;
        //    }
        //    nRet = Open(ref device);
        //    if (MyCamera.MV_OK != nRet)
        //    {
        //        OnError?.Invoke(_name, GetErrorInfo(nRet));
        //        return;
        //    }
        //    //注册回调函数
        //    ImageCallback1 = new ImageCallBack(mImageProvider_ImageReadyEvent);
        //    nRet = RegisterImageCallBack(ImageCallback1, IntPtr.Zero);
        //    //m_pOperator.Display(iptr.DisplayIniPtr);
        //    if (CO_OK != nRet)
        //    {
        //        OnError?.Invoke(_name, GetErrorInfo(nRet));
        //    }
        //    nRet = -1;
        //    ExcCallback1 = new ExceptionCallBack(ErrMsg);
        //    nRet = RegisterExceptionCallBack(ExcCallback1, IntPtr.Zero);
        //    if (CO_OK != nRet)
        //    {
        //        OnError?.Invoke(_name, GetErrorInfo(nRet));
        //    }
        //    SetTriggerMode(true);
        //    m_bOpen = true;
        //}

        public bool Init(IntPtr ptrCam)
        {
            int nRet = -1;
            //获取选择的设备信息
            MyCamera.MV_CC_DEVICE_INFO device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(ptrCam, typeof(MyCamera.MV_CC_DEVICE_INFO));
            if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
            {
                IntPtr buffer = Marshal.UnsafeAddrOfPinnedArrayElement(device.SpecialInfo.stGigEInfo, 0);

                MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)Marshal.PtrToStructure(buffer, typeof(MyCamera.MV_GIGE_DEVICE_INFO));

                _name = gigeInfo.chUserDefinedName;
            }
            //if (string.Compare(_name, name, true) != 0)
            //    return false;
            nRet = Open(ref device);
            if (MyCamera.MV_OK != nRet)
            {
                OnError?.Invoke(_name, GetErrorInfo(nRet));
                return false;
            }
            //注册回调函数
            ImageCallback1 = new ImageCallBack(mImageProvider_ImageReadyEvent);
            nRet = RegisterImageCallBack(ImageCallback1, IntPtr.Zero);
            //m_pOperator.Display(iptr.DisplayIniPtr);
            if (CO_OK != nRet)
            {
                OnError?.Invoke(_name, GetErrorInfo(nRet));
            }
            nRet = -1;
            ExcCallback1 = new ExceptionCallBack(ErrMsg);
            nRet = RegisterExceptionCallBack(ExcCallback1, IntPtr.Zero);
            if (CO_OK != nRet)
            {
                OnError?.Invoke(_name, GetErrorInfo(nRet));
            }
            m_bOpen = true;
            SetHeartBeatTimeout(3000);
            SetTriggerMode(true);


            return true;
        }

        public void Uninit()
        {
            if (_isPreview)
            {
                StopPreview();
                //标志位设为false
                _isPreview = false;
            }
            //停止采集
            Close();
            m_bOpen = false;
        }

        /// <summary>
        /// 启动获取图像
        /// </summary>
        public void StartPreview()
        {
            if (!_isPreview)
            {
                int nRet;
                nRet = m_Mycamera.MV_CC_StartGrabbing_NET();
                if (MyCamera.MV_OK != nRet)
                {
                    OnError?.Invoke(_name, GetErrorInfo(nRet));
                    return;
                }
                //标志位置位true
                _isPreview = true;
            }
        }

        /// <summary>
        /// 停止获取图像
        /// </summary>
        public void StopPreview()
        {
            if (_isPreview)
            {
                //停止采集
                int nRet = m_Mycamera.MV_CC_StopGrabbing_NET();
                //标志位设为false
                _isPreview = false;
            }
        }

        /// <summary>
        /// 抓拍
        /// </summary>
        public void Trigger()
        {
            //输出曝光增益
            //MyCamera.MVCC_FLOATVALUE stParam = new MyCamera.MVCC_FLOATVALUE();
            // m_Mycamera.MV_CC_GetFloatValue_NET("ExposureTime", ref stParam);
            //Console.WriteLine("曝光:" + stParam.fCurValue.ToString("F1"));
            //m_Mycamera.MV_CC_GetFloatValue_NET("Gain", ref stParam);
            //Console.WriteLine("增益:" + stParam.fCurValue.ToString("F1"));

            while (ImageQueue.Count > 0)
                ImageQueue.Dequeue().Dispose();

            if (_isPreview) StopPreview();
            ManualTrigger = false;
            SetTriggerMode(true);  //设置触发模式

            SetTriggerHardware(true);  //设置触发模式
            Thread.Sleep(1);
            SetTriggerHardware(false);  //设置触发模式
            StartPreview();
            //触发命令
            int nRet = CommandExecute("TriggerSoftware");
            for (int i = 0; i < 30; i++)
            {
                Thread.Sleep(100);
                if (ManualTrigger)
                {
                    break;
                }
            }
            StopPreview();
            if (CO_OK != nRet)
            {
                OnError?.Invoke(_name, GetErrorInfo(nRet));
            }
        }

        public void UserTrigger()
        {
            Trigger();
            Bitmap img = ImageQueue.Dequeue();
            ShowLiveImage(img);
        }

        public void Live()
        {
            SetTriggerMode(false);
            StartPreview();
        }

        private void CopyMemory(IntPtr dest, IntPtr src, int bytes)
        {
            byte[] buffer = new byte[bytes];
            Marshal.Copy(src, buffer, 0, bytes);
            Marshal.Copy(buffer, 0, dest, bytes);
        }

        UInt32 m_nRowStep = 0;

        private void mImageProvider_ImageReadyEvent(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO pFrameInfo, IntPtr pUser)
        {

            //ICogImage cogImage = null;
            Bitmap bmp = null;
            try
            {
                if (pFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8)
                {
                    //************************Mono8 转 Bitmap*******************************
                    bmp = new Bitmap(pFrameInfo.nWidth, pFrameInfo.nHeight, pFrameInfo.nWidth * 1, PixelFormat.Format8bppIndexed, pData);

                    // 创建一个颜色表（灰度）
                    ColorPalette palette = bmp.Palette;
                    for (int i = 0; i < 256; i++)
                    {
                        palette.Entries[i] = Color.FromArgb(i, i, i);
                    }
                    bmp.Palette = palette;

                    GC.Collect();
                }
                else
                {
                    bmp = new Bitmap(pFrameInfo.nWidth, pFrameInfo.nHeight, pFrameInfo.nWidth * 3, PixelFormat.Format24bppRgb, pData);

                    string filedir = $"{DateTime.Now.ToString("HHmmss")}" + ".bmp";
                    // 保存位图到本地文件
                    bmp.Save(filedir, ImageFormat.Bmp);

                    GC.Collect();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return;
            }
            if (bmp != null)
            {
                if (!IsContinuous)
                {
                    if (ImageQueue.Count >= MaxImageCount)
                        ImageQueue.Dequeue().Dispose();
                    ImageQueue.Enqueue(bmp);   //图像加入队列
                    ManualTrigger = true;
                    OnManualImage?.Invoke(_name);
                }
                else
                {
                    OnAutoImage?.Invoke(bmp);
                    //ShowLiveImage(image);
                }
            }
        }



        /// <summary>
        /// 使用本地图片
        /// </summary>
        /// <param name="fileName"></param>
        public bool LocalImage(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
                return false;
            FileInfo fi = new FileInfo(fileName);
            if (!fi.Exists)
                return false;
            Bitmap bitmap = new Bitmap(fileName);
            ImageQueue.Enqueue(bitmap);
            OnManualImage?.Invoke(_name);
            return true;
        }

        /// <summary>
        /// 清理图像队列
        /// </summary>
        public void ClearQueue()
        {
            while (ImageQueue.Count > 0)
            {
                ImageQueue.Dequeue().Dispose();
            }
        }

        /// <summary>
        /// 相机1异常事件
        /// </summary>
        /// <param name="nMsgType"></param>
        /// <param name="pUser"></param>
        private void ErrMsg(uint nMsgType, IntPtr pUser)
        {
            if (_isPreview)
            {
                StopPreview();
                _isPreview = false;
            }
            if (m_bOpen)
            {
                Close();
                m_bOpen = false;
            }
            OnError?.Invoke(_name, "摄像头异常");
            //if(MessageBox.Show("相机连接失败,是否重新连接相机,若重复出现该条提示,请选择[否],然后关闭本程序并重新打开!","提示:",MessageBoxButtons.YesNo)==DialogResult.Yes)
            //{
            //    Thread.Sleep(2000);
            //    restartCam();
            //}
        }

        /// <summary>
        /// 显示图片
        /// </summary>
        /// <param name="img"></param>
        public void ShowLiveImage(Bitmap img)
        {
            try
            {
                if (img != null)
                {
                    //VisionTools.ShowDisplayByImage(cogRecordDisplay, img);
                }
            }
            catch (Exception ex)
            {
                OnError?.Invoke(_name, ex.Message);
            }
            finally
            {
                if (img != null)
                {
                    img.Dispose();
                }
            }
        }

        /// <summary>
        /// 设置触发模式
        /// </summary>
        /// <param name="triggerModel">true:开启触发模式;false:关闭触发模式</param>
        public void SetTriggerMode(bool on)
        {
            if (m_bOpen)
            {
                if (on)
                {
                    SetEnumValue("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
                    IsContinuous = false;
                }
                else
                {
                    SetEnumValue("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF);
                    IsContinuous = true;
                }
            }
        }

        public void SetTriggerSource(uint source)
        {
            SetEnumValue("TriggerSource", source);
        }

        /// <summary>
        /// 设置触发模式
        /// </summary>
        /// <param name="mode">true,硬触发;false,软触发</param>
        public void SetTriggerHardware(bool mode)
        {
            SetTriggerSource(mode ? (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0 : (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
        }

        /// <summary>
        /// 设置增益
        /// </summary>
        /// <param name="gain">增益</param>
        public int SetGain(string gain)
        {
            MyCamera.MVCC_FLOATVALUE stParam = new MyCamera.MVCC_FLOATVALUE();
            m_Mycamera.MV_CC_GetFloatValue_NET("Gain", ref stParam);
            float setVal = Convert.ToSingle(gain);
            setVal = setVal < stParam.fMax ? setVal : stParam.fMax;
            SetEnumValue("GainAuto", 0);
            return SetFloatValue("Gain", setVal);
        }

        /// <summary>
        /// 获取增益
        /// </summary>
        /// <returns></returns>
        public string GetGain()
        {
            float stParam = 0;
            GetFloatValue("Gain", ref stParam);
            return stParam.ToString();
        }
        /// <summary>
        /// 设置曝光时间
        /// </summary>
        /// <param name="exposure"></param>
        public void SetExposure(string exposure)
        {
            MyCamera.MVCC_FLOATVALUE stParam = new MyCamera.MVCC_FLOATVALUE();
            m_Mycamera.MV_CC_GetFloatValue_NET("ExposureTimeAbs", ref stParam);
            float setVal = Convert.ToSingle(exposure);
            setVal = setVal > stParam.fMin ? setVal : stParam.fMin;
            SetEnumValue("ExposureAuto", 0);
            SetFloatValue("ExposureTimeAbs", setVal);
        }

        /// <summary>
        /// 获取曝光时间
        /// </summary>
        /// <returns></returns>
        public string GetExposure()
        {
            float stParam = 0;
            GetFloatValue("ExposureTime", ref stParam);
            return stParam.ToString();
        }

        #region 相机控制接口

        /****************************************************************************
         * @fn           Open
         * @brief        连接设备
         * @param        stDeviceInfo       IN       设备信息结构体
         * @return       成功：0；错误：-1
         ****************************************************************************/

        public int Open(ref MyCamera.MV_CC_DEVICE_INFO stDeviceInfo)
        {
            if (null == m_Mycamera)
            {
                m_Mycamera = new MyCamera();
                if (null == m_Mycamera)
                {
                    return CO_FAIL;
                }
            }

            int nRet;
            nRet = m_Mycamera.MV_CC_CreateDevice_NET(ref stDeviceInfo);
            if (MyCamera.MV_OK != nRet)
            {
                return nRet;
            }

            nRet = m_Mycamera.MV_CC_OpenDevice_NET();
            if (MyCamera.MV_OK != nRet)
            {
                return nRet;
            }
            return CO_OK;
        }

        /****************************************************************************
         * @fn           Close
         * @brief        关闭设备
         * @param        none
         * @return       成功：0；错误：-1
         ****************************************************************************/

        public int Close()
        {
            int nRet;

            nRet = m_Mycamera.MV_CC_CloseDevice_NET();
            if (MyCamera.MV_OK != nRet)
            {
                return CO_FAIL;
            }

            nRet = m_Mycamera.MV_CC_DestroyDevice_NET();
            if (MyCamera.MV_OK != nRet)
            {
                return CO_FAIL;
            }
            return CO_OK;
        }

        /****************************************************************************
         * @fn           RegisterImageCallBack
         * @brief        注册取流回调函数
         * @param        CallBackFunc          IN        回调函数
         * @param        pUser                 IN        用户参数
         * @return       成功：0；错误：-1
         ****************************************************************************/

        public int RegisterImageCallBack(ImageCallBack CallBackFunc, IntPtr pUser)
        {
            int nRet;
            nRet = m_Mycamera.MV_CC_RegisterImageCallBack_NET(CallBackFunc, pUser);
            if (MyCamera.MV_OK != nRet)
            {
                return CO_FAIL;
            }
            return CO_OK;
        }

        /****************************************************************************
         * @fn           RegisterExceptionCallBack
         * @brief        注册异常回调函数
         * @param        CallBackFunc          IN        回调函数
         * @param        pUser                 IN        用户参数
         * @return       成功：0；错误：-1
         ****************************************************************************/

        public int RegisterExceptionCallBack(ExceptionCallBack CallBackFunc, IntPtr pUser)
        {
            int nRet;
            nRet = m_Mycamera.MV_CC_RegisterExceptionCallBack_NET(CallBackFunc, pUser);
            if (MyCamera.MV_OK != nRet)
            {
                return CO_FAIL;
            }
            return CO_OK;
        }

        /****************************************************************************
        * @fn           GetIntValue
        * @brief        获取Int型参数值
        * @param        strKey                IN        参数键值，具体键值名称参考HikCameraNode.xls文档
        * @param        pnValue               OUT       返回值
        * @return       成功：0；错误：-1
        ****************************************************************************/

        public int GetIntValue(string strKey, ref uint pnValue)
        {
            MyCamera.MVCC_INTVALUE stParam = new MyCamera.MVCC_INTVALUE();
            int nRet = m_Mycamera.MV_CC_GetIntValue_NET(strKey, ref stParam);
            if (MyCamera.MV_OK != nRet)
            {
                return CO_FAIL;
            }

            pnValue = stParam.nCurValue;

            return CO_OK;
        }

        /****************************************************************************
         * @fn           SetIntValue
         * @brief        设置Int型参数值
         * @param        strKey                IN        参数键值，具体键值名称参考HikCameraNode.xls文档
         * @param        nValue                IN        设置参数值，具体取值范围参考HikCameraNode.xls文档
         * @return       成功：0；错误：-1
         ****************************************************************************/

        public int SetIntValue(string strKey, uint nValue)
        {
            int nRet = m_Mycamera.MV_CC_SetIntValue_NET(strKey, nValue);
            if (MyCamera.MV_OK != nRet)
            {
                return CO_FAIL;
            }
            return CO_OK;
        }

        /****************************************************************************
         * @fn           GetFloatValue
         * @brief        获取Float型参数值
         * @param        strKey                IN        参数键值，具体键值名称参考HikCameraNode.xls文档
         * @param        pValue                OUT       返回值
         * @return       成功：0；错误：-1
         ****************************************************************************/

        public int GetFloatValue(string strKey, ref float pfValue)
        {
            MyCamera.MVCC_FLOATVALUE stParam = new MyCamera.MVCC_FLOATVALUE();
            int nRet = m_Mycamera.MV_CC_GetFloatValue_NET(strKey, ref stParam);
            if (MyCamera.MV_OK != nRet)
            {
                return CO_FAIL;
            }

            pfValue = stParam.fCurValue;

            return CO_OK;
        }

        /****************************************************************************
         * @fn           SetFloatValue
         * @brief        设置Float型参数值
         * @param        strKey                IN        参数键值，具体键值名称参考HikCameraNode.xls文档
         * @param        fValue                IN        设置参数值，具体取值范围参考HikCameraNode.xls文档
         * @return       成功：0；错误：-1
         ****************************************************************************/

        public int SetFloatValue(string strKey, float fValue)
        {
            int nRet = m_Mycamera.MV_CC_SetFloatValue_NET(strKey, fValue);
            if (MyCamera.MV_OK != nRet)
            {
                return CO_FAIL;
            }
            return CO_OK;
        }

        /****************************************************************************
         * @fn           GetEnumValue
         * @brief        获取Enum型参数值
         * @param        strKey                IN        参数键值，具体键值名称参考HikCameraNode.xls文档
         * @param        pnValue               OUT       返回值
         * @return       成功：0；错误：-1
         ****************************************************************************/

        public int GetEnumValue(string strKey, ref uint pnValue)
        {
            MyCamera.MVCC_ENUMVALUE stParam = new MyCamera.MVCC_ENUMVALUE();
            int nRet = m_Mycamera.MV_CC_GetEnumValue_NET(strKey, ref stParam);
            if (MyCamera.MV_OK != nRet)
            {
                return CO_FAIL;
            }

            pnValue = stParam.nCurValue;

            return CO_OK;
        }

        /****************************************************************************
         * @fn           SetHeartBeatTimeout
         * @brief        设置SetHeartBeatTimeout
         * @param        pnValue               IN       ms
         * @return       成功：0；错误：-1
         ****************************************************************************/

        public int SetHeartBeatTimeout(uint pnValue)
        {
            // MV_CC_SetHeartBeatTimeout_NET((uint)3000);
            MyCamera.MVCC_ENUMVALUE stParam = new MyCamera.MVCC_ENUMVALUE();
            int nRet = m_Mycamera.MV_CC_SetHeartBeatTimeout_NET(pnValue);
            if (MyCamera.MV_OK != nRet)
            {
                return CO_FAIL;
            }
            return CO_OK;
        }

        /****************************************************************************
         * @fn           SetEnumValue
         * @brief        设置Enum型参数值
         * @param        strKey                IN        参数键值，具体键值名称参考HikCameraNode.xls文档
         * @param        nValue                IN        设置参数值，具体取值范围参考HikCameraNode.xls文档
         * @return       成功：0；错误：-1
         ****************************************************************************/

        public int SetEnumValue(string strKey, uint nValue)
        {
            int nRet = m_Mycamera.MV_CC_SetEnumValue_NET(strKey, nValue);
            if (MyCamera.MV_OK != nRet)
            {
                return CO_FAIL;
            }
            return CO_OK;
        }

        /****************************************************************************
         * @fn           GetBoolValue
         * @brief        获取Bool型参数值
         * @param        strKey                IN        参数键值，具体键值名称参考HikCameraNode.xls文档
         * @param        pbValue               OUT       返回值
         * @return       成功：0；错误：-1
         ****************************************************************************/

        public int GetBoolValue(string strKey, ref bool pbValue)
        {
            int nRet = m_Mycamera.MV_CC_GetBoolValue_NET(strKey, ref pbValue);
            if (MyCamera.MV_OK != nRet)
            {
                return CO_FAIL;
            }

            return CO_OK;
        }

        /****************************************************************************
         * @fn           SetBoolValue
         * @brief        设置Bool型参数值
         * @param        strKey                IN        参数键值，具体键值名称参考HikCameraNode.xls文档
         * @param        bValue                IN        设置参数值，具体取值范围参考HikCameraNode.xls文档
         * @return       成功：0；错误：-1
         ****************************************************************************/

        public int SetBoolValue(string strKey, bool bValue)
        {
            int nRet = m_Mycamera.MV_CC_SetBoolValue_NET(strKey, bValue);
            if (MyCamera.MV_OK != nRet)
            {
                return CO_FAIL;
            }
            return CO_OK;
        }

        /****************************************************************************
         * @fn           GetStringValue
         * @brief        获取String型参数值
         * @param        strKey                IN        参数键值，具体键值名称参考HikCameraNode.xls文档
         * @param        strValue              OUT       返回值
         * @return       成功：0；错误：-1
         ****************************************************************************/

        public int GetStringValue(string strKey, ref string strValue)
        {
            MyCamera.MVCC_STRINGVALUE stParam = new MyCamera.MVCC_STRINGVALUE();
            int nRet = m_Mycamera.MV_CC_GetStringValue_NET(strKey, ref stParam);
            if (MyCamera.MV_OK != nRet)
            {
                return CO_FAIL;
            }

            strValue = stParam.chCurValue;

            return CO_OK;
        }

        /****************************************************************************
         * @fn           SetStringValue
         * @brief        设置String型参数值
         * @param        strKey                IN        参数键值，具体键值名称参考HikCameraNode.xls文档
         * @param        strValue              IN        设置参数值，具体取值范围参考HikCameraNode.xls文档
         * @return       成功：0；错误：-1
         ****************************************************************************/

        public int SetStringValue(string strKey, string strValue)
        {
            int nRet = m_Mycamera.MV_CC_SetStringValue_NET(strKey, strValue);
            if (MyCamera.MV_OK != nRet)
            {
                return CO_FAIL;
            }
            return CO_OK;
        }

        /****************************************************************************
         * @fn           CommandExecute
         * @brief        Command命令
         * @param        strKey                IN        参数键值，具体键值名称参考HikCameraNode.xls文档
         * @return       成功：0；错误：-1
         ****************************************************************************/

        public int CommandExecute(string strKey)
        {
            int nRet = m_Mycamera.MV_CC_SetCommandValue_NET(strKey);
            if (MyCamera.MV_OK != nRet)
            {
                return CO_FAIL;
            }
            return CO_OK;
        }

        #endregion

        #region 静态全局方法

        /****************************************************************************
         * @fn           EnumDevices
         * @brief        枚举可连接设备
         * @param        nLayerType       IN         传输层协议：1-GigE; 4-USB;可叠加
         * @param        stDeviceList     OUT        设备列表
         * @return       成功：0；错误：错误码
         ****************************************************************************/

        public static int EnumDevices(uint nLayerType, ref MyCamera.MV_CC_DEVICE_INFO_LIST stDeviceList)
        {
            return MyCamera.MV_CC_EnumDevices_NET(nLayerType, ref stDeviceList);
        }

        /// <summary>
        /// 获取相机操作异常信息
        /// </summary>
        /// <param name="nErrorNum"></param>
        /// <returns></returns>
        public static string GetErrorInfo(int nErrorNum)
        {
            string errorMsg = "";
            switch (nErrorNum)
            {
                case MyCamera.MV_E_HANDLE: errorMsg += " 错误或无效句柄 "; break;
                case MyCamera.MV_E_SUPPORT: errorMsg += " 不支持的功能"; break;
                case MyCamera.MV_E_BUFOVER: errorMsg += " 缓存已满 "; break;
                case MyCamera.MV_E_CALLORDER: errorMsg += "函数调用顺序错误"; break;
                case MyCamera.MV_E_PARAMETER: errorMsg += " 参数不正确"; break;
                case MyCamera.MV_E_RESOURCE: errorMsg += " 应用资源失败 "; break;
                case MyCamera.MV_E_NODATA: errorMsg += "没有数据"; break;
                case MyCamera.MV_E_PRECONDITION: errorMsg += " 前置条件错误，或运行环境改变 "; break;
                case MyCamera.MV_E_VERSION: errorMsg += "版本不匹配 "; break;
                case MyCamera.MV_E_NOENOUGH_BUF: errorMsg += "内存不足 "; break;
                case MyCamera.MV_E_UNKNOW: errorMsg += " 未知错误"; break;
                case MyCamera.MV_E_GC_GENERIC: errorMsg += " 一般错误 "; break;
                case MyCamera.MV_E_GC_ACCESS: errorMsg += " 节点访问条件错误"; break;
                case MyCamera.MV_E_ACCESS_DENIED: errorMsg += "没有权限"; break;
                case MyCamera.MV_E_BUSY: errorMsg += " 设备忙，或网络断开"; break;
                case MyCamera.MV_E_NETER: errorMsg += " 网络错误 "; break;
            }
            return errorMsg;
        }

        /// <summary>
        /// 枚举相机
        /// </summary>
        public static int EnumDevices(ref List<IntPtr> ptrList)
        {
            MyCamera.MV_CC_DEVICE_INFO_LIST deviceList = new MyCamera.MV_CC_DEVICE_INFO_LIST();
            int nRet = EnumDevices(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref deviceList);
            if (deviceList.nDeviceNum > 0)
            {
                foreach (IntPtr ptr in deviceList.pDeviceInfo)
                {
                    if (ptr != IntPtr.Zero)
                    {
                        ptrList.Add(ptr);
                    }
                }
            }
            return nRet;
        }

        #endregion
    }
}
